home *** CD-ROM | disk | FTP | other *** search
- // ==================================================
- // CTouchMeDialogDD.cp
- // Copyright (C) 1996 Mizutori Tetsuya, July 4 1996, August 4, 1996.
- // ==================================================
- // All documents are pretty-printed in Geneva 10-point font.
-
- #include <LPane.h>
- #include <LDragTask.h>
- #include <UDrawingState.h>
- #include <UDrawingUtils.h>
- #include <LBroadcaster.h>
- #include <LCommander.h>
-
- #include <PP_Messages.h>
-
- #include "touchMeConstants.h"
- #include "CTouchMeDialog.h"
- #include "CTouchMeDialogDD.h"
- #include "CDateEditField.h"
-
- /*****
- enum {
- flavorTypeHFS = 'hfs ',
- flavorTypePromiseHFS = 'phfs',
- flavorTypeDirectory = 'diry'
- };
-
- typedef struct HFSFlavor {
- OSType fileType;
- OSType fileCreator;
- unsigned short fdFlags;
- FSSpec fileSpec;
- } HFSFlavor;
- *****/
-
- const PaneIDT thePaneList[8] = {
- kTmeD_CrTextEditDate, kTmeD_CrTextEditTime,
- kTmeD_MdTextEditDate, kTmeD_MdTextEditTime,
- kNoPaneID };
-
-
- // ==================================================
- // Drag and Drop
- // ==================================================
-
- // --------------------------------------------------
- // ・ ItemIsAcceptable
- // --------------------------------------------------
-
- Boolean
- CTouchMeDialog::ItemIsAcceptable(
- DragReference inDragRef,
- ItemReference inItemRef )
- {
- Boolean theResult = false;
- FlavorFlags theFlags;
-
- // Accept only HFS-type files, which are dragged from Finder.
- theResult = IsEnabled() &&
- ( ::GetFlavorFlags( inDragRef, inItemRef, flavorTypeHFS, &theFlags ) == noErr );
-
- return theResult;
- }
-
-
- // --------------------------------------------------
- // ・ ReceiveDragItem
- // --------------------------------------------------
-
- void
- CTouchMeDialog::ReceiveDragItem(
- DragReference inDragRef,
- DragAttributes inDragAttrs,
- ItemReference inItemRef,
- Rect &inItemBounds )
- {
- #pragma unused( inDragAttrs, inItemBounds )
- OSErr err;
-
- FlavorFlags theFlags;
- err = ::GetFlavorFlags( inDragRef, inItemRef, flavorTypeHFS, &theFlags );
- ThrowIfOSErr_( err );
-
- // Get the flavor data.
- HFSFlavor theHFSFlavor;
- Size theDataSize = sizeof( HFSFlavor );
- err = ::GetFlavorData( inDragRef, inItemRef,
- flavorTypeHFS, (void *) &theHFSFlavor, &theDataSize, 0 );
- ThrowIfOSErr_( err );
-
- // Get the FSSPec data from the flavor.
- FSSpec theFSSpec;
- theFSSpec = theHFSFlavor.fileSpec;
-
- if ( mModifier ) {
- // if ( IsModifierKeyPressed( inDragRef ) ) {
-
- // Do execute 'touch' theFSSpec, if the option-key is pressed.
- ProcessCommand( cmd_Touch, (void *) &theFSSpec );
-
- } else {
-
- // Set date time EditFields by the stamp of theFSSpec, if no modifier key is pressed.
- // If the file was dropped on some EditField, then the only one EditField will be changed.
- // Now, get the mouse location and convert to port coordinates.
- Point thePoint;
- ::GetDragMouse( inDragRef, &thePoint, nil );
- GlobalToPortPoint( thePoint );
-
- PaneIDT thePaneID = FindPaneByMouse( thePoint );
-
- switch ( thePaneID ) {
- case kTmeD_CrTextEditDate:
- BroadcastMessage( msg_TmeD_DroppedFileCrDate, (void *) &theFSSpec ); break;
- case kTmeD_CrTextEditTime:
- BroadcastMessage( msg_TmeD_DroppedFileCrTime, (void *) &theFSSpec ); break;
- case kTmeD_MdTextEditDate:
- BroadcastMessage( msg_TmeD_DroppedFileMdDate, (void *) &theFSSpec ); break;
- case kTmeD_MdTextEditTime:
- BroadcastMessage( msg_TmeD_DroppedFileMdTime, (void *) &theFSSpec ); break;
- default:
- BroadcastMessage( msg_TmeD_DroppedFile, (void *) &theFSSpec ); break;
- }
-
- }
- }
-
-
- // --------------------------------------------------
- // ・ EnterDropArea
- // --------------------------------------------------
-
- void
- CTouchMeDialog::EnterDropArea(
- DragReference inDragRef,
- Boolean inDragHasLeftSender )
- {
- // Call inherited.
- LDragAndDrop::EnterDropArea( inDragRef, inDragHasLeftSender );
-
- // Check the status of modifier keys, whether it is pressed or not.
- mModifier = IsModifierKeyPressed( inDragRef );
-
- // Invalidate the last hilite pane.
- mHilitePaneID = kNoPaneID;
-
- // Remember the last (latent) target before a drag & drop operation.
- // mTargetID = kNoPaneID; // This time, we do not use ID number.
- mTarget = nil;
-
- // Get the EditField as a target commander among four EditFields.
- // If the dialog is in front, then 'GetTarget()' returns the target EditField.
- // If it is not in front or in background, then the dialog itself is a latent sub commander,
- // so that the desired EditField is to be get by 'GetLatentSub()' of the dialog.
- LCommander * theTarget = GetTarget();
- LCommander * theLatentTarget = GetLatentSub();
- if ( theLatentTarget != nil )
- theTarget = theLatentTarget->GetLatentSub();
-
- if ( theTarget != nil ) {
- // If a target exists, it must be an EditField and then should be deactivated.
- // You can confirm which the target is a type of EditField, as follows.
- // PaneIDT iPaneID, iTargetPaneID;
- // iTargetPaneID = ((CDateEditField *) theTarget)->GetPaneID();
- // Boolean found=false;
- // for ( short i=0; (iPaneID=thePaneList[i]) != kNoPaneID; i++ )
- // if ( iTargetPaneID == iPaneID ) { found=true; }
- // if ( found ) mTargetID = iTargetPaneID;
- mTarget = theTarget;
- // Let's deactivate the TE field because the hilite color can be
- // distinguished between colors by selection and HiliteRect().
- mTEActive = ((CDateEditField *) theTarget)->GetTEActive();
- ((CDateEditField *) theTarget)->SetTEActive( false );
- }
- }
-
-
- // --------------------------------------------------
- // ・ LeaveDropArea
- // --------------------------------------------------
-
- void
- CTouchMeDialog::LeaveDropArea(
- DragReference inDragRef )
- {
- // Check the status of modifier keys, which is pressed or not.
- mModifier = false;
-
- // Invalidate the last hilite pane.
- HilitePane( mHilitePaneID );
- mHilitePaneID = kNoPaneID;
-
- // Restore the last (latent) target before a drag & drop operation.
- // if ( mTargetID != kNoPaneID ) { // This time, we do not use ID number.
- if ( mTarget != nil ) {
- // LCommander * theTarget = (LCommander *) FindPaneByID( mTargetID );
- // SwitchTarget( theTarget );
- ((CDateEditField *) mTarget)->SetTEActive( mTEActive );
- }
- // mTargetID = kNoPaneID;
- mTarget = nil;
-
- // Call inherited.
- LDragAndDrop::LeaveDropArea( inDragRef );
- }
-
-
- // --------------------------------------------------
- // ・ InsideDropArea
- // --------------------------------------------------
-
- void
- CTouchMeDialog::InsideDropArea(
- DragReference inDragRef )
- {
- // Call inherited.
- LDragAndDrop::InsideDropArea( inDragRef );
-
- // If option-key is pressed, then hilite area is the bound of this dialog box.
- // if ( IsModifierKeyPressed( inDragRef ) ) return;
- if ( mModifier ) return;
-
- // Set the current port to this dialog.
- if ( ! FocusDraw() ) return;
-
- // Get the mouse location and convert to port coordinates.
- Point thePoint;
- ::GetDragMouse( inDragRef, &thePoint, nil );
- GlobalToPortPoint( thePoint );
-
- // If dragging position is in some EditField, then the EditField turns to be hilited.
- PaneIDT thePaneID = FindPaneByMouse( thePoint );
- if ( thePaneID != mHilitePaneID ) HilitePane( thePaneID );
- }
-
-
- // --------------------------------------------------
- // ・ HiliteDropArea
- // --------------------------------------------------
-
- void
- CTouchMeDialog::HiliteDropArea(
- DragReference inDragRef )
- {
- RgnHandle theHiliteRgnH = ::NewRgn();
-
- // I do not know why 'mModifier' is not updated as the one of 'EnterDropArea()'. ???
- // if ( mModifier ) {
- if ( IsModifierKeyPressed(inDragRef) ) {
-
- // If option-key is pressed, the hilite region is the dialog rect.
- Rect theRect;
- CalcLocalFrameRect( theRect );
- ::RectRgn( theHiliteRgnH, &theRect );
- FocusDraw(); // 'Focus()' and 'Refresh()' seems to be required here,
- Refresh(); // otherwise the 'ShowDragHilite()' does not work properly.
-
- } else {
-
- // If no modifier key is pressed, the hilite region is a union of EditFields.
- RgnHandle theRgnH = ::NewRgn();
- PaneIDT iPaneID;
- // Get hilite region.
- for ( short i=0; (iPaneID=thePaneList[i]) != kNoPaneID; i++ ) {
- Rect theRect;
- LPane *thePane;
- thePane = (LPane *) FindPaneByID( iPaneID );
- thePane->FocusDraw(); // 'Focus()' and 'Refresh()' seems to be required here,
- thePane->Refresh(); // otherwise the 'ShowDragHilite()' does not work properly.
- thePane->CalcPortFrameRect( theRect );
- ::RectRgn( theRgnH, &theRect );
- ::UnionRgn( theHiliteRgnH, theRgnH, theHiliteRgnH );
- }
- ::DisposeRgn( theRgnH );
-
- }
-
- ::ShowDragHilite( inDragRef, theHiliteRgnH, true );
-
- ::DisposeRgn( theHiliteRgnH );
- }
-
-
- // ==================================================
- // Common functions
- // ==================================================
-
- // --------------------------------------------------
- // ・ IsModifierKeyPressed
- // --------------------------------------------------
-
- Boolean
- CTouchMeDialog::IsModifierKeyPressed(
- DragReference inDragRef )
- {
- short theModifiers, theMouseDownModifiers, theMouseUpModifiers;
-
- ::GetDragModifiers( inDragRef,
- &theModifiers, &theMouseDownModifiers, &theMouseUpModifiers );
-
- return (Boolean) ( (theModifiers & optionKey ) != 0 );
- }
-
-
- // --------------------------------------------------
- // ・ FindPaneByMouse
- // --------------------------------------------------
-
- PaneIDT
- CTouchMeDialog::FindPaneByMouse(
- const Point inPoint )
- {
- PaneIDT iPaneID;
-
- for ( short i=0; (iPaneID=thePaneList[i]) != kNoPaneID; i++ ) {
- Rect theRect;
- LPane *thePane;
- thePane = (LPane *) FindPaneByID( iPaneID );
- thePane->CalcPortFrameRect( theRect );
- if ( ::PtInRect( inPoint, &theRect ) ) return iPaneID;
- }
-
- return (PaneIDT) kNoPaneID;
- }
-
-
- // --------------------------------------------------
- // ・ HilitePane
- // --------------------------------------------------
-
- void
- CTouchMeDialog::HilitePane(
- const PaneIDT inPaneID )
- {
- // Set the current port to this dialog.
- if ( ! FocusDraw() ) return;
-
- // Restore the previous one.
- if ( mHilitePaneID != kNoPaneID ) {
- LPane * thePane = (LPane *) FindPaneByID( mHilitePaneID );
- Rect theRect;
- thePane->CalcPortFrameRect( theRect );
- HiliteRect( theRect );
- }
-
- if ( inPaneID == mHilitePaneID ) return;
-
- // Setup the present one.
- if ( inPaneID != kNoPaneID ) {
- LPane * thePane = (LPane *) FindPaneByID( inPaneID );
- Rect theRect;
- thePane->CalcPortFrameRect( theRect );
- HiliteRect( theRect );
- }
-
- mHilitePaneID = inPaneID;
- }
-
-
- // --------------------------------------------------
- // ・ HiliteRect
- // --------------------------------------------------
- #include <LowMem.h>
-
- void
- CTouchMeDialog::HiliteRect(
- const Rect & inRect )
- {
- // From "Highlighting" section in p.4-41,
- // Apple Computer's Inside Macintosh "Imaging with QuickDraw".
-
- UInt8 theHiliteMode;
- theHiliteMode = ::LMGetHiliteMode();
- // theHiliteMode &= ~( (UInt8) 0x01 << hiliteBit );
- ::BitClr( &theHiliteMode, pHiliteBit );
- ::LMSetHiliteMode( theHiliteMode );
-
- ::InvertRect( &inRect );
- }
-
-
- // --------------------------------------------------
- // ・ Indicator
- // --------------------------------------------------
- // I prefer to show a very tiny spot at the corner to indicate the status.
-
- void
- CTouchMeDialog::Indicator(
- const Boolean inStatus )
- {
- static Boolean gStatus = false;
-
- if ( inStatus != gStatus && FocusDraw() ) {
- Rect theRect;
- ::SetRect( &theRect, 3, 3, 8, 8 ); // (left,top,right,bottom)
- if ( inStatus ) ::FillRect( &theRect, &(qd.gray) );
- else ::EraseRect( &theRect );
- }
-
- gStatus = inStatus;
- }
-
- // end of program
-